package com.winit.openapi.sms;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.winit.common.query.Page;
import com.winit.common.spi.SPIException;
import com.winit.common.spi.context.CommandContext;
import com.winit.erp.spi.bpartner.vo.Bpartner;
import com.winit.mms.spi.common.DateUtils;
import com.winit.openapi.constants.ApiConstant;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.sms.common.SmsUtils;
import com.winit.sms.spi.common.vo.PageVo;
import com.winit.sms.spi.wallet.bill.BillService;
import com.winit.sms.spi.wallet.bill.command.ModifyBillCommand;
import com.winit.sms.spi.wallet.bill.command.QueryBillByBillTimeCommand;
import com.winit.sms.spi.wallet.bill.command.QueryBillRecordCommand;
import com.winit.sms.spi.wallet.bill.vo.BillDetailsVo;
import com.winit.sms.spi.wallet.bill.vo.BillVo;
import com.winit.sms.spi.wallet.creditaccount.vo.CreditAccountLineVo;

/**
 * 账单
 * 
 * @version <pre>
 * Author	Version		Date		Changes
 * xiangui.fang 	1.0  		2016年1月27日 	Created
 *
 * </pre>
 * @since 1.
 */
@Controller
@RequestMapping("/sms/bill")
public class BillController extends BaseController {

    private static Logger logger = LoggerFactory.getLogger(BillController.class);
    @Resource
    private BillService   billService;

    /**
     * 账单分页查询
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/pageQueryBill")
    public String pageQueryBill(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {

        QueryBillRecordCommand command = SmsUtils.toJavaObject(requestMsg.getData(), QueryBillRecordCommand.class);
        CommandContext ctx = CommandContext.getContext();
        command.setCtx(ctx);
        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (bpartner == null) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }

        command.setCustomerCode(bpartner.getValue());
        PageVo pageVo = SmsUtils.SetPageParams(requestMsg.getData());
        command.setPageVo(pageVo);

        try {
            Page<BillVo> pagelist = billService.pageQueryBill(command);
            Map<String, Object> data = SmsUtils.setPageData(pagelist);
            responseMsg.setData(data);
        } catch (Exception e) {
            logger.error("<======pageQueryBill：", e);
        }
        return SUCCESS;

    }

    /**
     * 查询该客户账单的所有账单时间
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/queryAllBillTime")
    public String queryAllBillTime(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryBillByBillTimeCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            QueryBillByBillTimeCommand.class);
        CommandContext ctx = CommandContext.getContext();
        command.setCtx(ctx);
        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (null == bpartner) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }
        String customerCode = bpartner.getValue();// 客户编码
        command.setCustomerCode(customerCode);
        PageVo pageVo = SmsUtils.SetPageParams(requestMsg.getData());
        command.setPageVo(pageVo);
        // 获得该客户指定年份的所有账单时间 
        Page<BillVo> billList = billService.queryAllBillTime(command);
        if (null == billList) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>list为空");
            return ERROR;
        }
        for (BillVo tmp : billList.content) {
            tmp.setBilldateFrom(DateUtils.format(DateUtils.format(tmp.getBilldateFrom()), "yyyy-MM-dd"));
            tmp.setBilldateTo(DateUtils.format(DateUtils.format(tmp.getBilldateTo()), "yyyy-MM-dd"));
        }
        Map<String, Object> data = SmsUtils.setPageData(billList);

        responseMsg.setData(data);

        return SUCCESS;
    }

    /**
     * 查询该客户账单的所有账单时间
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/queryAllBillYear")
    public String queryAllBillYear(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryBillByBillTimeCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            QueryBillByBillTimeCommand.class);
        CommandContext ctx = CommandContext.getContext();
        command.setCtx(ctx);
        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (null == bpartner) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }
        String customerCode = bpartner.getValue();// 客户编码
        command.setCustomerCode(customerCode);
        // 获得该客户指定年份的所有账单时间
        BillVo billVo = billService.queryFirstBillTime(command);
        if (null == billVo) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>账单为空");
            return ERROR;
        }
        int billTimeYear = Integer.valueOf(billVo.getBillTime().substring(0, 4));
        int thisYear = DateUtils.getYear(new Date());
        List<Integer> yearList = new ArrayList<Integer>();
        for (int i = 0; i <= thisYear - billTimeYear; i++) {
            yearList.add(thisYear - i);
        }
        responseMsg.setData(yearList);
        return SUCCESS;
    }

    /**
     * 根据账单时间查询该客户账单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/queryBillByBillTime")
    public String queryBillByBillTime(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryBillByBillTimeCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            QueryBillByBillTimeCommand.class);
        CommandContext ctx = CommandContext.getContext();
        command.setCtx(ctx);
        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (null == bpartner) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }
        String customerCode = bpartner.getValue();// 客户编码
        command.setCustomerCode(customerCode);
        BillVo bill = billService.queryBillByBillTime(command);// 根据账单时间查询账单
        // 已出账单分页查询
        PageVo page = SmsUtils.SetPageParams(requestMsg.getData());
        command.setPageVo(page);
        Page<CreditAccountLineVo> creditAcctList = billService.pageCurrencyCreditAccountLine(command);// 本期信用账单交易明细
        BillDetailsVo billDetails = billService.queryBillDetails(command);// 本期账单详情
        if (null == bill) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>queryBillByBillTime查询账单为空");
            return ERROR;
        }
        if (null == creditAcctList) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>creditAcctList查询本期账单明细为空");
            return ERROR;
        }
        if (null == billDetails) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>billDetails查询本期账单详情为空");
            return ERROR;
        }
        // 已出账单（分页）
        Map<String, Object> pageCurrencyBill = SmsUtils.setPageData(creditAcctList);

        Map<String, Object> responseMap = new HashMap<String, Object>();
        responseMap.put("bill", bill);
        responseMap.put("pageCurrencyBill", pageCurrencyBill);
        responseMap.put("billDetails", billDetails);
        responseMsg.setData(responseMap);
        return SUCCESS;
    }

    /**
     * 根据账单时间查询该客户未出账单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/queryUnCurrencyCreditAccountLine")
    public String queryUnCurrencyCreditAccountLine(@ModelAttribute RequestMsg requestMsg,
                                                   @ModelAttribute ResponseMsg responseMsg) {
        QueryBillByBillTimeCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            QueryBillByBillTimeCommand.class);
        CommandContext ctx = CommandContext.getContext();
        command.setCtx(ctx);
        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (null == bpartner) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }
        String customerCode = bpartner.getValue();// 客户编码
        command.setCustomerCode(customerCode);
        PageVo pageVo = SmsUtils.SetPageParams(requestMsg.getData());
        command.setPageVo(pageVo);
        Page<CreditAccountLineVo> unGenerateBill = billService.queryUnCurrencyCreditAccountLine(command);
        if (null == unGenerateBill) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>unGenerateBill查询本期未出账单明细为空");
            return ERROR;
        }
        Map<String, Object> data = SmsUtils.setPageData(unGenerateBill);
        responseMsg.setData(data);
        return SUCCESS;
    }

    /**
     * 系统校验【本期账户余额】与（【上期账户余额】-【本期支出】+【本期收入】）金额是否一致
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/checkSystemBanlance")
    public String checkSystemBanlance(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryBillByBillTimeCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            QueryBillByBillTimeCommand.class);
        CommandContext ctx = CommandContext.getContext();
        command.setCtx(ctx);
        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (null == bpartner) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }
        String customerCode = bpartner.getValue();// 客户编码
        command.setCustomerCode(customerCode);
        try {
            responseMsg.setData(billService.checkSystemBanlance(command));
        } catch (Exception e) {
            throw new ApiException(ErrorCode.SYSTEM_ERROR);
        }
        return SUCCESS;
    }

    /**
     *  导出isp/海外仓 信用账单 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/queryCreditAccountLineExport")
    public String queryCreditAccountLineExport(@ModelAttribute RequestMsg requestMsg,
                                               @ModelAttribute ResponseMsg responseMsg) {
        QueryBillByBillTimeCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            QueryBillByBillTimeCommand.class);
        CommandContext ctx = CommandContext.getContext();
        command.setCtx(ctx);

        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (null == bpartner) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }

        String customerCode = bpartner.getValue();// 客户编码
        command.setCustomerCode(customerCode);

        String isok = null;
        try {
            isok = billService.queryCreditAccountLineExport(command);
        } catch (Exception e) {
            throw new ApiException(ErrorCode.SYSTEM_ERROR);
        }
        responseMsg.setData(isok);
        return SUCCESS;
    }

    /**
     *  导出isp/海外仓 未出账单 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/queryForExportUnCurrency")
    public String queryForExportUnCurrency(@ModelAttribute RequestMsg requestMsg,
                                           @ModelAttribute ResponseMsg responseMsg) {
        QueryBillByBillTimeCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            QueryBillByBillTimeCommand.class);
        CommandContext ctx = CommandContext.getContext();
        command.setCtx(ctx);
        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (null == bpartner) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }

        String customerCode = bpartner.getValue();// 客户编码
        command.setCustomerCode(customerCode);

        String isok = null;
        try {
            isok = billService.queryForExportUnCurrency(command);
        } catch (Exception e) {
            throw new ApiException(ErrorCode.SYSTEM_ERROR);
        }
        responseMsg.setData(isok);
        return SUCCESS;
    }

    /**
     *  查询最新信用账单
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/queryLastCreditBill")
    public String queryLastCreditBill(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryBillByBillTimeCommand command = new QueryBillByBillTimeCommand();
        CommandContext ctx = CommandContext.getContext();
        command.setCtx(ctx);

        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (null == bpartner) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }

        String customerCode = bpartner.getValue();// 客户编码
        command.setCustomerCode(customerCode);

        List<BillVo> list = null;
        try {
            list = billService.queryLastCreditBill(command);
        } catch (Exception e) {
            throw new ApiException(ErrorCode.SYSTEM_ERROR);
        }
        responseMsg.setData(list);
        return SUCCESS;
    }

    /**
     * 按年查询帐单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     * @throws ParseException
     */
    @RequestMapping(value = "/queryBillByYear")
    public String pageBillByYear(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg)
                                                                                                                     throws ParseException {
    	QueryBillRecordCommand command = SmsUtils.toJavaObject(requestMsg.getData(), QueryBillRecordCommand.class);
        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (bpartner == null) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }
        command.setCustomerCode(bpartner.getValue());
        try {
            Page<BillVo> pageBill = billService.pageQueryBill(command);
            List<String> yearList = new ArrayList<String>();
            List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
            for (BillVo vo : pageBill.getContent()) {
                String year = String.valueOf(DateUtils.getYear(vo.getBilldateFrom()));
                Map<String, Object> tempMap = new HashMap<String, Object>();
                tempMap.put("billdateFrom", vo.getBilldateFrom());
                tempMap.put("billdateTo", vo.getBilldateTo());
                tempMap.put("Year", year);
                listMap.add(tempMap);
                if (!yearList.contains(year)) {
                    yearList.add(year);
                }
            }
            Map<String, Object> dataAll = new HashMap<String, Object>();
            List<Map<String, Object>> tmpListMapALL = new ArrayList<Map<String, Object>>();
            for (String year : yearList) {
                List<Map<String, Object>> tmpListMap = new ArrayList<Map<String, Object>>();
                for (Map<String, Object> map : listMap) {
                    if (year.equals(map.get("Year").toString())) {
                        tmpListMap.add(map);
                    }
                }
                dataAll.put("Year", year);
                dataAll.put("list", tmpListMap);
                tmpListMapALL.add(dataAll);
                dataAll = new HashMap<String, Object>();
            }
            responseMsg.setData(tmpListMapALL);
        } catch (Exception e) {
            throw new ApiException(ErrorCode.SYSTEM_ERROR);
        }
        return SUCCESS;
    }
    
    /**
     * 生成电子发票
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/modifyVoucherUrlById")
    public String modifyVoucherUrlById(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
    	ModifyBillCommand modifyBillCommand = new ModifyBillCommand();
        try {
        	modifyBillCommand = SmsUtils.toJavaObject(requestMsg.getData(), ModifyBillCommand.class);
            CommandContext ctx = CommandContext.getContext();
            modifyBillCommand.setCtx(ctx);
            String url = billService.modifyVoucherUrlById(modifyBillCommand);
            responseMsg.setData(url);
        } catch (SPIException e) {
            logger.error("生成电子发票异常，ID:{},{}", modifyBillCommand.getId() + "", e.getMessage());
            responseMsg.setCode(e.getErrorCode());
            responseMsg.setMsg(e.getErrorMsg());
            return ERROR;
        }
        return SUCCESS;
    }
}
